package cn.hinglo.permission.controller;

import cn.hinglo.baseservice.annotation.IgnoreToken;
import cn.hinglo.baseservice.base.BaseController;
import cn.hinglo.common.constant.SystemConstant;
import cn.hinglo.common.entity.Result;
import cn.hinglo.common.utils.JwtUtil;
import cn.hinglo.permission.bean.model.User;
import cn.hinglo.permission.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author HingLo
 * @createTime: 2018/11/15 15:10
 * @description: 登录相关
 */
@RequestMapping("/u")
@RestController
@Validated
@CacheConfig(cacheNames = SystemConstant.PERMISSION)
public class LoginController extends BaseController {

    private final LoginService loginService;

    @Autowired
    public LoginController(LoginService loginService) {
        this.loginService = loginService;
    }

    /**
     * 所有系统中的用户使用此接口进行登录到后台进行管理,注意:按照规范,password字段不应再代码中出现注释
     *
     * @param username 用户名
     * @return 返回结果
     */
    @PostMapping("login")
    public Result login(@NotNull(message = "用户名不能为空") String username, @NotNull(message = "密码不能为空") String password) {
        User user = loginService.loginMethodService(username, password);
        if (user == null) {
            return error("账号或者密码错误");
        } else {
            // 查找全部的权限，然后进行返回给用户
            List<Map<String, Object>> list = loginService.findPermissionService(user.getId());
            // 查找菜单
            List<Map<String, Object>> menuList = loginService.findMenuService(user.getId());
            String token = JwtUtil.createJWT(user.getId().toString(), user.toString());
            response.setHeader(SystemConstant.AUTHORIZATION, token);
            Map<String, Object> map = new HashMap<>(2);
            map.put("permission", list);
            map.put("menu", menuList);
            // 查询系统中可用服务
            map.put("service", loginService.listService());
            // 调用权限查询方法进行权限缓存
            getOrSetPermission(user.getId(), list);
            return success(map);
        }
    }

    /***
     * 修改密码(所有用户都有此功能,无需要权限)
     *
     * @param newPassword 新密码
     * @return 返回结果
     */
    @PutMapping("updatePasswd")
    @IgnoreToken
    public Result updatePasswd(String password, String newPassword) {
        String userId = getSessionAttr(SystemConstant.PERMISSION_USER_ID);
        return loginService.updatePasswd(userId, password, newPassword);
    }

    /***
     * 该方法也是权限校验方法,权限拦截器使用该模块进行获取用户权限
     *
     * @param userId 用户ID
     * @return 返回结果, 用于使用注解缓存
     */
    @GetMapping("permissionList")
    public Result getUserPermission(Integer userId) {
        return success(getOrSetPermission(userId, null));
    }

    /**
     * 1:登录成后,将权限信息缓存到系统中(首次校验权限时候,减少数据库查询操作),目前使用EHcache进行缓存,如果将来需要,更换缓存驱动<br>
     * 2:同时为权限校验模块提供用户的权限信息,并缓存
     *
     * @param userId 用户Id
     * @param list   权限集合
     * @return 返回集合
     */
    @Cacheable(value = SystemConstant.PERMISSION, key = "#userId")
    public List<String> getOrSetPermission(Integer userId, List<Map<String, Object>> list) {
        if (list == null) {
            list = loginService.findPermissionService(userId);
        }
        List<String> permissionList = new ArrayList<>(list.size());
        list.forEach(x -> permissionList.add((String) x.get("url")));
        return permissionList;
    }

}
